package main

import (
	"encoding/json"
	"fmt"
)

const (
	CC_Register   = 1
	CC_Calculate1 = 2
	CC_Calculate2 = 3
)

var commands = map[int]*Handler{}

type Handler struct {
	command int
	handle  HandleFunc
	factory RequestFactory
}

func (h *Handler) Invoke(data []byte) (int, interface{}) {
	// codec
	r := h.factory()
	err := json.Unmarshal(data, r)
	if err != nil {
		return -1, nil
	}
	return h.handle(r)
}

type HandleFunc func(interface{}) (int, interface{})

type RequestFactory func() interface{}

func RegisterHandle(command int, handle HandleFunc, factory RequestFactory) {
	if _, ok := commands[command]; ok {
		panic(fmt.Sprintf("duplicate command %v", command))
	}

	commands[command] = &Handler{
		command: command,
		handle:  handle,
		factory: factory,
	}
}

func GetHandler(command int) *Handler {
	return commands[command]
}
